Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX: Accommodate Python 3 in DICOM slice sorting #728

Merged
merged 6 commits into from
Mar 18, 2019

Conversation

reddigari
Copy link
Contributor

Looks like list.sort() in Python 3 requires a key instead of cmp parameter, which has to be given as a keyword argument.

The function that uses them (nicom.dicomreaders.slices_to_series()) doesn't have a test, and I wasn't sure whether there was any appropriate test data to use in one, so I didn't write one. I'd be happy to if someone has thoughts on what data to use.

@coveralls
Copy link

coveralls commented Feb 26, 2019

Coverage Status

Coverage increased (+0.2%) to 92.099% when pulling 5a30076 on reddigari:master into ad0b13f on nipy:master.

@effigies
Copy link
Member

effigies commented Mar 1, 2019

Thanks for this. Can you provide a minimal reproduction of the issue you ran into? Given that, it might be easier to write a test.

@effigies effigies added this to the 2.4.0 milestone Mar 1, 2019
@reddigari
Copy link
Contributor Author

I can't provide the DICOMs I was using, but any should do:

import glob
from nibabel.nicom import dicomreaders

fnames = glob.glob("*.dcm")
wrappers = [dicomreaders.wrapper_from_file(f) for f in fnames]
series = dicomreaders.slices_to_series(wrappers)

Output before commit:

Traceback (most recent call last):
  File nibabel_test.py, line 9, in <module>
    series = dicomreaders.slices_to_series(wrappers)
  File /home/brainspec/Tools/nibabel/nibabel/nicom/dicomreaders.py, line 149, in slices_to_series
    vol_list.sort(_slice_sorter)
TypeError: must use keyword argument for key function

@effigies
Copy link
Member

effigies commented Mar 1, 2019

Cool. There are some .dcm files in nibabel/tests/data/, if you'd like to put together a test. That file looks pretty under-covered.

@codecov-io
Copy link

codecov-io commented Mar 1, 2019

Codecov Report

Merging #728 into master will increase coverage by 0.17%.
The diff coverage is 66.66%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #728      +/-   ##
==========================================
+ Coverage   89.39%   89.56%   +0.17%     
==========================================
  Files          93       93              
  Lines       11476    11511      +35     
  Branches     1992     2002      +10     
==========================================
+ Hits        10259    10310      +51     
+ Misses        881      861      -20     
- Partials      336      340       +4
Impacted Files Coverage Δ
nibabel/nicom/dicomreaders.py 59.18% <66.66%> (+16.32%) ⬆️
nibabel/cmdline/parrec2nii.py 32.73% <0%> (ø) ⬆️
nibabel/testing/__init__.py 96.18% <0%> (+1.39%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ad0b13f...5a30076. Read the comment docs.

@reddigari
Copy link
Contributor Author

Apologies for the gross derivation of the test data path, all the other tests in that suite use data in nicom/tests/data, so I had to use relative paths back up to nibabel/tests/data.

Not sure why coverage didn't change; I can't find any other tests that call slices_to_series.

@effigies
Copy link
Member

effigies commented Mar 1, 2019

So it looks like there are actually separate DICOMs in nibabel/nicom/tests/data, and this directory is already available through the IO_DATA_PATH variable.

As to the coverage, it did update, but because AppVeyor is failing, CodeCov isn't updating the comment.

The AppVeyor failure looks unrelated, so don't worry about that.

@reddigari
Copy link
Contributor Author

It was my understanding that this function is meant to take single-slice dicoms from one or more series, separate them into series, and then sort the slices (apparently only along the z-dimension). The two test files I used in nibabel/tests/data are from the same series, so I thought they'd be the better choice.

Additionally, one of the two dicoms in nibabel/nicom/tests/data is a multiframe dicom, so it's less clear to me how the slice sorter should handle it.

Let me know your thoughts on how/whether to proceed. Perhaps we can copy the two files I used into the nicom test data directory, use all the .dcm files (except maybe the multiframe one), and add a test to make sure it separates the series?

@effigies effigies changed the title FIX: accommodate Python 3 in DICOM slice sorting FIX: Accommodate Python 3 in DICOM slice sorting Mar 8, 2019
Copy link
Member

@effigies effigies left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. This looks good. I don't suppose there's any chance of digging up a file that hits the _third_pass condition?

if len(set(zs)) < len(zs): # not unique zs
# third pass
out_vol_lists += _third_pass(vol_list)
continue

@reddigari
Copy link
Contributor Author

We could duplicate one of the slices, and append it to the list of wrappers. That should register as a duplicated z-value, and call _third_pass(). We can probably fidget with its instance_number attribute to fully cover the function.

I might be able to tackle that some time this weekend, if you think it's the right move.

@effigies
Copy link
Member

effigies commented Mar 8, 2019

On the whole more coverage is better, but it should be a valid DICOM. I'll confess to knowing little about the format, so I don't know if what you describe is normal or something that will technically work but isn't actually valid. Another thing to consider is looking through PyDICOM's test data directory for something that triggers this code.

@effigies effigies mentioned this pull request Mar 15, 2019
20 tasks
@effigies
Copy link
Member

I'm going to go ahead and merge. If you get a chance to add a new test file, it would be highly appreciated.

@effigies effigies merged commit 9430224 into nipy:master Mar 18, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants